package com.xbh.wificonfiglib.util;

import android.content.Context;
import android.content.SharedPreferences;

import java.io.File;
import java.util.Map;

// import androidx.annotation.NonNull;
// import androidx.core.content.ContextCompat;


/**
 * SharePreference工具类
 *
 * @author LANGO
 * @date 2018/11/22
 */
public class SPUtil {

    /**
     * 保存在sp的文件名
     */
    public static final String SP_FILE_NAME = "sp_xbh";

    /**
     * 得到保存数据的方法，我们根据默认值得到保存的数据的具体类型，然后调用相对应的方法获取值
     *
     * @param context
     * @param key
     * @param defaultValue
     * @return
     */
    public static String get(Context context, String key, String defaultValue) {
        return get(context, SP_FILE_NAME, key, defaultValue);
    }

    /**
     * 得到保存数据的方法，我们根据默认值得到保存的数据的具体类型，然后调用相对应的方法获取值
     *
     * @param context
     * @param key
     * @param defaultValue
     * @return
     */
    public static String get(Context context, String spName, String key, String defaultValue) {
        SharedPreferences sp = context.getSharedPreferences(spName, Context.MODE_PRIVATE);
        return sp.getString(key, defaultValue);
    }

    /**
     * 得到保存数据的方法，我们根据默认值得到保存的数据的具体类型，然后调用相对应的方法获取值
     *
     * @param context
     * @param key
     * @param defaultValue
     * @return
     */
    public static Long get(Context context, String key, Long defaultValue) {
        return get(context, SP_FILE_NAME, key, defaultValue);
    }

    /**
     * 得到保存数据的方法，我们根据默认值得到保存的数据的具体类型，然后调用相对应的方法获取值
     *
     * @param context
     * @param key
     * @param defaultValue
     * @return
     */
    public static Long get(Context context, String spName, String key, Long defaultValue) {
        SharedPreferences sp = context.getSharedPreferences(spName, Context.MODE_PRIVATE);
        return sp.getLong(key, defaultValue);
    }

    /**
     * 得到保存数据的方法，我们根据默认值得到保存的数据的具体类型，然后调用相对应的方法获取值
     *
     * @param context
     * @param key
     * @param defaultValue
     * @return
     */
    public static Integer get(Context context, String key, Integer defaultValue) {
        return get(context, SP_FILE_NAME, key, defaultValue);
    }

    /**
     * 得到保存数据的方法，我们根据默认值得到保存的数据的具体类型，然后调用相对应的方法获取值
     *
     * @param context
     * @param key
     * @param defaultValue
     * @return
     */
    public static Integer get(Context context, String spName, String key, Integer defaultValue) {
        SharedPreferences sp = context.getSharedPreferences(spName, Context.MODE_PRIVATE);
        return sp.getInt(key, defaultValue);
    }

    /**
     * 得到保存数据的方法，我们根据默认值得到保存的数据的具体类型，然后调用相对应的方法获取值
     *
     * @param context
     * @param key
     * @param defaultValue
     * @return
     */
    public static Boolean get(Context context, String key, Boolean defaultValue) {
        return get(context, SP_FILE_NAME, key, defaultValue);
    }

    /**
     * 得到保存数据的方法，我们根据默认值得到保存的数据的具体类型，然后调用相对应的方法获取值
     *
     * @param context
     * @param key
     * @param defaultValue
     * @return
     */
    public static Boolean get(Context context, String spName, String key, Boolean defaultValue) {
        SharedPreferences sp = context.getSharedPreferences(spName, Context.MODE_PRIVATE);
        return sp.getBoolean(key, defaultValue);
    }

    /**
     * 得到保存数据的方法，我们根据默认值得到保存的数据的具体类型，然后调用相对应的方法获取值
     *
     * @param context
     * @param key
     * @param defaultValue
     * @return
     */
    public static Float get(Context context, String key, Float defaultValue) {
        return get(context, SP_FILE_NAME, key, defaultValue);
    }

    /**
     * 得到保存数据的方法，我们根据默认值得到保存的数据的具体类型，然后调用相对应的方法获取值
     *
     * @param context
     * @param key
     * @param defaultValue
     * @return
     */
    public static Float get(Context context, String spName, String key, Float defaultValue) {
        SharedPreferences sp = context.getSharedPreferences(spName, Context.MODE_PRIVATE);
        return sp.getFloat(key, defaultValue);
    }

    /**
     * 返回所有的键值对
     *
     * @param context
     * @return
     */
    public static Map<String, ?> getAll(Context context) {
        SharedPreferences sp = context.getSharedPreferences(SP_FILE_NAME, Context.MODE_PRIVATE);
        return sp.getAll();
    }

    /**
     * 返回所有的键值对
     *
     * @param context
     * @return
     */
    public static Map<String, ?> getAll(Context context, String spName) {
        SharedPreferences sp = context.getSharedPreferences(spName, Context.MODE_PRIVATE);
        return sp.getAll();
    }

    /**
     * 批量保存数据的方法
     *
     * @param context
     * @param map
     */
    public static void putMap(Context context, Map<String, Object> map) throws Exception {
        putMap(context, SP_FILE_NAME, map);
    }

    /**
     * 批量保存数据的方法
     *
     * @param context
     * @param spName
     * @param map
     */
    public static void putMap(Context context, String spName, Map<String, Object> map) throws Exception {
        for (Map.Entry entry : map.entrySet()) {
            // 遍历map集合,匹配不同的value类型
            String key = entry.getKey().toString();
            Object object = entry.getValue();
            if (object instanceof String) {
                put(context, spName, key, (String) object);
            } else if (object instanceof Integer) {
                put(context, spName, key, (Integer) object);
            } else if (object instanceof Boolean) {
                put(context, spName, key, (Boolean) object);
            } else if (object instanceof Float) {
                put(context, spName, key, (Float) object);
            } else if (object instanceof Long) {
                put(context, spName, key, (Long) object);
            } else {
                throw new Exception("Can't save custom object!");
            }
        }
    }

    /**
     * 保存数据的方法，我们需要拿到保存数据的具体类型，然后根据类型调用不同的保存方法
     *
     * @param context
     * @param key
     * @param value
     */
    public static void put(Context context, String spName, String key, String value) {
        // 不让其他应用读取该文件，即私有
        SharedPreferences sp = context.getSharedPreferences(spName, Context.MODE_PRIVATE);
        SharedPreferences.Editor editor = sp.edit();
        editor.putString(key, value);
        SharedPreferencesCompat.apply(editor);
    }

    /**
     * 保存数据的方法，我们需要拿到保存数据的具体类型，然后根据类型调用不同的保存方法
     *
     * @param context
     * @param key
     * @param value
     */
    public static void put(Context context, String spName, String key, Integer value) {
        // 不让其他应用读取该文件，即私有
        SharedPreferences sp = context.getSharedPreferences(spName, Context.MODE_PRIVATE);
        SharedPreferences.Editor editor = sp.edit();
        editor.putInt(key, value);
        SharedPreferencesCompat.apply(editor);
    }

    /**
     * 保存数据的方法，我们需要拿到保存数据的具体类型，然后根据类型调用不同的保存方法
     *
     * @param context
     * @param key
     * @param value
     */
    public static void put(Context context, String spName, String key, Boolean value) {
        // 不让其他应用读取该文件，即私有
        SharedPreferences sp = context.getSharedPreferences(spName, Context.MODE_PRIVATE);
        SharedPreferences.Editor editor = sp.edit();
        editor.putBoolean(key, value);
        SharedPreferencesCompat.apply(editor);
    }

    /**
     * 保存数据的方法，我们需要拿到保存数据的具体类型，然后根据类型调用不同的保存方法
     *
     * @param context
     * @param key
     * @param value
     */
    public static void put(Context context, String spName, String key, Float value) {
        // 不让其他应用读取该文件，即私有
        SharedPreferences sp = context.getSharedPreferences(spName, Context.MODE_PRIVATE);
        SharedPreferences.Editor editor = sp.edit();
        editor.putFloat(key, value);
        SharedPreferencesCompat.apply(editor);
    }

    /**
     * 保存数据的方法，我们需要拿到保存数据的具体类型，然后根据类型调用不同的保存方法
     *
     * @param context
     * @param key
     * @param value
     */
    public static void put(Context context, String spName, String key, Long value) {
        // 不让其他应用读取该文件，即私有
        SharedPreferences sp = context.getSharedPreferences(spName, Context.MODE_PRIVATE);
        SharedPreferences.Editor editor = sp.edit();
        editor.putLong(key, value);
        SharedPreferencesCompat.apply(editor);
    }

    /**
     * 保存数据的方法，我们需要拿到保存数据的具体类型，然后根据类型调用不同的保存方法
     *
     * @param context
     * @param key
     * @param value
     */
    public static void put(Context context, String key, String value) {
        put(context, SP_FILE_NAME, key, value);
    }

    /**
     * 保存数据的方法，我们需要拿到保存数据的具体类型，然后根据类型调用不同的保存方法
     *
     * @param context
     * @param key
     * @param value
     */
    public static void put(Context context, String key, Integer value) {
        put(context, SP_FILE_NAME, key, value);
    }

    /**
     * 保存数据的方法，我们需要拿到保存数据的具体类型，然后根据类型调用不同的保存方法
     *
     * @param context
     * @param key
     * @param value
     */
    public static void put(Context context, String key, Boolean value) {
        put(context, SP_FILE_NAME, key, value);
    }

    /**
     * 保存数据的方法，我们需要拿到保存数据的具体类型，然后根据类型调用不同的保存方法
     *
     * @param context
     * @param key
     * @param value
     */
    public static void put(Context context, String key, Float value) {
        put(context, SP_FILE_NAME, key, value);
    }

    /**
     * 保存数据的方法，我们需要拿到保存数据的具体类型，然后根据类型调用不同的保存方法
     *
     * @param context
     * @param key
     * @param value
     */
    public static void put(Context context, String key, Long value) {
        put(context, SP_FILE_NAME, key, value);
    }

    /**
     * 移除某个key值已经对应的值
     *
     * @param context
     * @param key
     */
    public static void removeKey(Context context, String key) {
        removeKey(context, SP_FILE_NAME, key);
    }

    /**
     * 移除某个key值已经对应的值
     *
     * @param context
     * @param key
     */
    public static void removeKey(Context context, String spName, String key) {
        SharedPreferences sp = context.getSharedPreferences(spName, Context.MODE_PRIVATE);
        SharedPreferences.Editor editor = sp.edit();
        editor.remove(key);
        SharedPreferencesCompat.apply(editor);
    }

    /**
     * 清除所有数据
     *
     * @param context
     */
    public static void clear(Context context) {
        clear(context, SP_FILE_NAME);
    }

    /**
     * 清除所有数据
     *
     * @param context
     */
    public static void clear(Context context, String spName) {
        SharedPreferences sp = context.getSharedPreferences(spName, Context.MODE_PRIVATE);
        SharedPreferences.Editor editor = sp.edit();
        editor.clear();
        SharedPreferencesCompat.apply(editor);
    }

    /**
     * 查询某个key是否已经存在
     *
     * @param context
     * @param key
     * @return
     */
    public static boolean contains(Context context, String key) {
        return contains(context, key);
    }

    /**
     * 查询某个key是否已经存在
     *
     * @param context
     * @param spName
     * @param key
     * @return
     */
    public static boolean contains(Context context, String spName, String key) {
        SharedPreferences sp = context.getSharedPreferences(spName, Context.MODE_PRIVATE);
        return sp.contains(key);
    }


    /**
     * 判断sp文件是否存在
     */
    public static boolean isExist(Context context) {
        File file = new File("/data/data/" + context.getPackageName().toString()
                + "/shared_prefs", SP_FILE_NAME + ".xml");
        if (file.exists()) {
            return true;
        } else {
            return false;
        }
    }

    /**
     * 判断sp文件是否存在
     */
    public static boolean isExist(Context context, String spName) {
        File file = new File("/data/data/" + context.getPackageName().toString()
                + "/shared_prefs", spName + ".xml");
        if (file.exists()) {
            return true;
        } else {
            return false;
        }
    }

    /**
     * 删除sp文件
     *
     * @return
     */
    public static boolean deleteSP(Context context) {
        return deleteSP(context, SP_FILE_NAME);
    }

    /**
     * 删除sp文件
     *
     * @return
     */
    public static boolean deleteSP(Context context, String spName) {
        File file = new File(context.getDataDir() + context.getPackageName().toString()
                + "/shared_prefs", spName + ".xml");
        return file.exists() && file.delete();
    }

    /**
     * 创建一个解决SharedPreferencesCompat.apply方法的一个兼容类
     */
    private static class SharedPreferencesCompat {

        /**
         * 如果找到则使用apply执行，否则使用commit
         *
         * @param editor
         */
        public static void apply(SharedPreferences.Editor editor) {
            try {
                editor.apply();
                return;
            } catch (Exception e) {
                e.printStackTrace();
            }
            editor.commit();
        }
    }

}
